﻿package net.wangit.user.admin;

import java.util.Map;

import net.wangit.MapList;
import net.wangit.Row;
import net.wangit.framework.util.MapListUtil;
import net.wangit.jdbc.DB;
import net.wangit.jdbc.DBFactory;
import net.wangit.jdbc.Type;
import net.wangit.user.privilege.PrivilegeUtil;
import net.wangit.util.Checker;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;


public class AdminFactory {

	private static final Log log = LogFactory
			.getLog(net.wangit.user.admin.AdminFactory.class);
	private static final String SQL_ADMINISTRATOR = "select * from AADMIN where adminid=?";
	private static final String SQL_ORGANIZATIONS = "select orgid from AADMINORG where adminid=?";
	private static final String SQL_GROUPS = "select groupid from AADMINGROUP where adminid=?";
	private static final String SQL_ROLES = "select roleid from AADMINROLE where adminid=?";
	private static final String SQL_INDIRECT_ROLES = "select roleid from AROLE  where  roleid in (select t1.roleid from AORGROLE t1,AADMINORG t2 where t1.orgid = t2.orgid and t2.adminid=?) or roleid in (select t3.roleid from AGROUPROLE t3,AADMINGROUP t4 where t3.groupid = t4.groupid and t4.adminid=?)";
	private static final String SQL_PRIVILEGES = "select * from AROLEPRIVILEGE where roleid not in (select roleid from AROLE where enabled=0) and ( roleid in (select roleid from AROLE where parentid is null or parentid='') or roleid in (select roleid from AADMINROLE where adminid=?) or roleid in (select t1.roleid from AORGROLE t1,AADMINORG t2 where t1.orgid = t2.orgid and t2.adminid=?) or roleid in (select t3.roleid from AGROUPROLE t3,AADMINGROUP t4 where t3.groupid = t4.groupid and t4.adminid=? and t3.groupid not in (select groupid from AGROUP where enabled=0)))";

	public AdminFactory() {
	}

	public static Admin getAdmin(String aid) {
		Admin administrator = AdminCache.get(aid);
		if (administrator == null) {
			administrator = createAdmin(aid);
			AdminCache.put(aid, administrator);
		}
		return administrator;
	}

	private static Admin createAdmin(String aid) {
		DB db;
		MapList list;
		try {
			db = DBFactory.getDB();
			list = db.query(AdminFactory.SQL_ADMINISTRATOR, aid, Type.VARCHAR);
			if (Checker.isEmpty(list))
				return null;
			Admin administrator;
			Row row = list.getRow(0);
			administrator = new Admin(aid);
			administrator.setName(row.get("adminname"));
			administrator.setAuthorizationEnabled("1".equals(row
					.get("authenabled")));
			administrator.setOrganizations(getOrganizations(db, aid));
			administrator.setGroups(getGroups(db, aid));
			administrator.setRoles(getRoles(db, aid));
			administrator.setIndirectRoles(getIndirectRoles(db, aid));
			administrator.setAllRolesCount();
			administrator.setPrivileges(getPrivileges(db, aid));
			return administrator;
		} catch (Exception e) {
			log.debug("create Administrator error:", e);
			return null;
		}
	}

	private static String[] getOrganizations(DB db, String aid)
			throws Exception {
		MapList list = db.query(AdminFactory.SQL_ORGANIZATIONS, aid,
				Type.VARCHAR);
		return MapListUtil.getArray(list, "orgid");
	}

	private static String[] getGroups(DB db, String aid) throws Exception {
		MapList list = db.query(AdminFactory.SQL_GROUPS, aid, Type.VARCHAR);
		return MapListUtil.getArray(list, "groupid");
	}

	private static String[] getRoles(DB db, String aid) throws Exception {
		MapList list = db.query(AdminFactory.SQL_ROLES, aid, Type.VARCHAR);
		return MapListUtil.getArray(list, "roleid");
	}

	private static String[] getIndirectRoles(DB db, String aid)
			throws Exception {
		MapList list = db.query(AdminFactory.SQL_INDIRECT_ROLES, new String[] {
				aid, aid }, new int[] { Type.VARCHAR, Type.VARCHAR });
		return MapListUtil.getArray(list, "roleid");
	}

	private static Map getPrivileges(DB db, String aid) throws Exception {
		MapList list = db.query(AdminFactory.SQL_PRIVILEGES, new String[] {
				aid, aid, aid }, new int[] { Type.VARCHAR, Type.VARCHAR,
				Type.VARCHAR });
		return PrivilegeUtil.getPrivileges(list);
	}

}
